#include "SettingConfigUI.h"

#define TITLE_HEIGHT 40

static void textarea_click_event_cb(lv_event_t *e);
static void keyboard_close_btn_click_event_cb(lv_event_t *e);

// LCD分辨率
static uint32_t lcdW = 480;
static uint32_t lcdH = 272;

// 字体
static lv_font_t *fontText;

// 配置页签
static lv_obj_t *tabview = nullptr;

// 输入键盘
static lv_obj_t *keyboard;

// 页面容器
std::vector<lv_obj_t *> *pageVector;

/**
 * @brief 创建配置UI
 * @param parent 父对象
 */
lv_obj_t *SettingUI::createConfigUI(lv_obj_t *parent, lv_font_t *_fontText)
{
    fontText = _fontText;

    lcdW = lv_disp_get_hor_res(nullptr);
    lcdH = lv_disp_get_ver_res(nullptr);

    tabview = lv_tabview_create(parent, LV_DIR_TOP, 45);
    lv_obj_set_size(tabview, lcdW, lcdH - TITLE_HEIGHT);
    lv_obj_align(tabview, LV_ALIGN_BOTTOM_MID, 0, 0);

    keyboard = lv_keyboard_create(lv_layer_top());
    lv_keyboard_set_popovers(keyboard, true);
    lv_obj_set_size(keyboard, lcdW, lcdH / 2);
    lv_obj_set_style_text_font(keyboard, &lv_font_montserrat_24, LV_STATE_DEFAULT | LV_PART_ITEMS);
    lv_obj_add_flag(keyboard, LV_OBJ_FLAG_HIDDEN); // 隐藏键盘
    lv_obj_add_event_cb(keyboard, keyboard_close_btn_click_event_cb, LV_EVENT_CANCEL, nullptr);
    lv_obj_add_event_cb(keyboard, keyboard_close_btn_click_event_cb, LV_EVENT_READY, nullptr);

    pageVector = new std::vector<lv_obj_t *>;

    return tabview;
}

/**
 * @brief 释放配置UI
 */
void SettingUI::releaseConfigUI(void)
{
    if (tabview == nullptr)
        return;

    int totalPage = pageVector->size();

    for (auto page : *pageVector)
    {
        lv_obj_t *list = (lv_obj_t *)lv_obj_get_user_data(page);

        lv_obj_t *btn = lv_obj_get_child(list, -1);
        while (btn != nullptr)
        {
            lv_obj_t *textarea = (lv_obj_t *)lv_obj_get_user_data(btn);
            if (textarea != nullptr)
            {
                ConfigItemInfo *info = (ConfigItemInfo *)lv_obj_get_user_data(textarea);
                if (info != nullptr)
                    delete info; // 释放配置项信息数据内存
            }

            lv_obj_del(btn);
            btn = lv_obj_get_child(list, -1);
        }
    }

    lv_obj_del(tabview);
    tabview = nullptr;

    lv_obj_del(keyboard);
    keyboard = nullptr;

    delete pageVector;
}

/**
 * @brief 添加一个配置页面
 * @param name 配置页面名称
 * @retval 配置页面索引
 */
int SettingUI::addConfigPage(std::string &name)
{
    lv_obj_t *page = lv_tabview_add_tab(tabview, name.c_str());
    lv_obj_set_style_pad_all(page, 0, LV_STATE_DEFAULT); // 填充为0

    lv_coord_t pageW = lv_obj_get_width(tabview);
    lv_coord_t pageH = lv_obj_get_height(tabview) - 45;

    lv_obj_t *list = lv_list_create(page);
    lv_obj_set_size(list, pageW, pageH - 80);
    lv_obj_align(list, LV_ALIGN_TOP_MID, 0, 0);
    lv_obj_set_style_radius(list, 0, LV_STATE_DEFAULT); // 边框圆角为0

    lv_obj_set_user_data(page, list);

    pageVector->push_back(page);

    return pageVector->size() - 1;
}

/**
 * @brief 添加一个配置项到配置页面
 * @param page 配置页面索引
 * @param info 配置项信息
 */
void SettingUI::addConfigItem(int pageIndex, ConfigItemInfo &info)
{
    if (pageIndex >= pageVector->size())
        return;

    lv_obj_t *page = pageVector->at(pageIndex);
    lv_obj_t *list = (lv_obj_t *)lv_obj_get_user_data(page);

    const char *itemName = info.name.c_str();
    if (info.nameZh != "")
        itemName = info.nameZh.c_str();

    // 添加一个按钮到list
    lv_obj_t *btn = lv_list_add_btn(list, nullptr, itemName);
    lv_obj_set_style_text_font(btn, fontText, LV_STATE_DEFAULT); // 设置字体
    lv_obj_clear_flag(btn, LV_OBJ_FLAG_CLICKABLE | LV_OBJ_FLAG_CHECKABLE | LV_OBJ_FLAG_SCROLLABLE);

    // 添加一个文本框到btn
    lv_obj_t *textarea = lv_textarea_create(btn);
    lv_obj_set_width(textarea, lv_obj_get_width(btn) / 2);
    lv_textarea_set_align(textarea, LV_TEXT_ALIGN_RIGHT);                            // 右对齐
    lv_textarea_set_one_line(textarea, true);                                        // 设置单行模式
    lv_obj_set_style_text_font(textarea, fontText, LV_STATE_DEFAULT);                // 设置字体
    lv_obj_set_style_text_color(textarea, lv_color_hex(0x2c2c2c), LV_STATE_DEFAULT); // 字体颜色
    lv_obj_clear_flag(textarea, LV_OBJ_FLAG_SCROLLABLE);                             // 禁止滚动
    lv_obj_align(textarea, LV_ALIGN_RIGHT_MID, 0, 0);
    lv_obj_add_event_cb(textarea, textarea_click_event_cb, LV_EVENT_CLICKED, nullptr);

    ConfigItemInfo *infoCopy = new ConfigItemInfo();
    *infoCopy = info;  
    lv_obj_set_user_data(btn, textarea);      // 保存文本框
    lv_obj_set_user_data(textarea, infoCopy); // 保存配置项

    const char *placeholderText = "";
    char text[32] = "";
    switch (info.type)
    {
    case Config_Number:
        placeholderText = "数值参数";
        snprintf(text, 32, "%d", info.value);
        lv_textarea_set_accepted_chars(textarea, "0123456789-."); // 设置可输入字符
        break;
    case Config_String:
        placeholderText = "字符串参数";
        snprintf(text, 32, "%s", info.string.c_str());
        break;
    default:;
    }

    lv_textarea_set_placeholder_text(textarea, placeholderText); // 设置占位文本
    lv_textarea_set_text(textarea, text);                        // 设置文本
}

/**
 * @brief 获取某一页配置项容器(更新后的配置信息)
 */
std::vector<SettingUI::ConfigItemInfo> *SettingUI::getPageConfigItemVector(int pageIndex)
{
    if (pageIndex >= pageVector->size())
        return nullptr;

    lv_obj_t *page = pageVector->at(pageIndex);
    lv_obj_t *list = (lv_obj_t *)lv_obj_get_user_data(page);

    int btnCnt = lv_obj_get_child_cnt(list);

    for(int i = 0; i < btnCnt; i++)     // 检查是否有空参数
    {
        lv_obj_t *btn = lv_obj_get_child(list, i);
        if (btn != nullptr)
        {
            lv_obj_t *textarea = (lv_obj_t *)lv_obj_get_user_data(btn);
            const char *text = lv_textarea_get_text(textarea);
            if(text == nullptr || text[0] == '\0')
                return nullptr;     // 有参数为空
        }
    }

    auto itemVector = new std::vector<ConfigItemInfo>;

    for (int i = 0; i < btnCnt; i++)        // 更新配置信息
    {
        lv_obj_t *btn = lv_obj_get_child(list, i);
        if (btn != nullptr)
        {
            lv_obj_t *textarea = (lv_obj_t *)lv_obj_get_user_data(btn);
            if (textarea != nullptr)
            {
                ConfigItemInfo *info = (ConfigItemInfo *)lv_obj_get_user_data(textarea);
                if (info != nullptr)
                {
                    const char *text = lv_textarea_get_text(textarea);

                    switch (info->type)
                    {
                    case Config_Number:
                        info->value = atoi(text);
                        break;
                    case Config_String:
                        info->string = text;
                        break;
                    default:;
                    }
                    itemVector->push_back(*info);
                }
            }
        }
    }

    return itemVector;
}

/**
 * @brief textarea点击事件回调函数
 */
static void textarea_click_event_cb(lv_event_t *e)
{
    lv_obj_t *textarea = lv_event_get_current_target(e);

    lv_keyboard_set_textarea(keyboard, textarea);

    if (lv_obj_has_flag(keyboard, LV_OBJ_FLAG_HIDDEN))
        lv_obj_clear_flag(keyboard, LV_OBJ_FLAG_HIDDEN);
}

/**
 * @brief keyboard关闭按钮点击事件回调函数
 */
static void keyboard_close_btn_click_event_cb(lv_event_t *e)
{
    lv_obj_t *_keyboard = lv_event_get_current_target(e);

    lv_obj_add_flag(_keyboard, LV_OBJ_FLAG_HIDDEN);
}
